package com.zisu.springcloud.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

/**
 * @Author: 蔡翔
 * @Date: 2020/9/26 11:36
 * @Version 1.0
 *
 * 流控
 */
@RestController
public class FlowLimitController
{
    //流量控制 首先是拿到这个Rest接口地址 来进行控制

    int i = 0;
    //sentinel  QPS模式 ： 就是 限制1s 钟处理几个请求
    @GetMapping("/testA")
    public String testA() {
        System.out.println(Thread.currentThread().getName()+i++);
        return "------testA";
    }


    @GetMapping("/testB")
    public String testB() {
//sentinel  线程模式 ： 就是 只用一个线程处理请求，如果一个请求没处理完另外一个请求就进来了，会直接报错
//        try {
//            Thread.sleep(800);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        return "------testB";
    }



    //服务降级
    @GetMapping("/testD")
    public String testD()
    {
        //1. RT 模式  （就是慢调用比例）
//        try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
//        System.out.println("testD 测试RT");
        //2.异常比例  (只有在 每秒请求大于“你设定的值” 并且失败比例大于“你设定的值” ，才会触发熔断 如果没有够到你达到要求就会普通报错)
        int a = 10/0;
        return "------testD";
    }

    @GetMapping("/testE")
    public String testE()
    {
        //3.异常数 （时间窗 必须大于60，然后失败数到达阈值 才会 熔断）
        int a = 10/0;
        return "------testD";
    }

    //当在配置热点规则的时候 ，资源名 那一栏  /testHotKey 说明是从接口那里过来(也就是@GetMapping里面的) 的，如果是testHotKey 说明是从@SentinelResource 接口配置这里来的
    @GetMapping("/testHotKey")
    //这个注解的意思就是,当这个接口违背了nacos 上配置的规则（热点规则），那么将采用下面testHotKey() 兜底的方法来执行
    //无论这个接口的参数传过来 几个 都是要准守 nacos里面的热点规则的（nacos上可以设置特例），，value是热点名 ，blockHandler是 兜底方法名
    //注意 注意sentinel上有个参数所有0 所以 第一个参数必须要传入 否者不会进入管控范围
    @SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")
    public String deal_testHotKey(@RequestParam(value = "p1",required = false) String p1,
                                    @RequestParam(value = "p2",required = false) String p2
    ){
        return "____testHotKey";
    }
    public String deal_testHotKey(String p1, String p2, BlockException blockException){
        return "_______deal_testHotKey,fail";
    }

}